home *** CD-ROM | disk | FTP | other *** search
- unit DBRestr;
- (* April 1997, Author : Roberto De Marini,
- e-mail : rdemari@poboxes.com *)
- interface
-
- uses
- DB,DBTables,{$IFDEF Win32} Bde {$ELSE} DbiTypes,DbiProcs {$ENDIF};
-
- type
- TResOp = (resADD,resDROP,resMODIFY,resMOVE);
-
- procedure Restructure(ATable:TTable; OpType: TResOp; FNum, FDest: integer;
- FName: string; FType: TFieldType; FSize: word);
-
-
-
- implementation
-
- uses
- SysUtils,{$IFDEF Win32}DBRUtl32 {$ELSE}DBRUtl16 {$ENDIF};
-
-
- procedure Restructure(ATable:TTable; OpType: TResOP; FNum,FDest: integer;
- FName: string; FType: TFieldType; FSize: word);
- type
- TFldArr = array[1..1000] of FldDesc;
- TOpArr = array[1..1000] of CROpType;
- var
- hDb: hDbiDb;
- TblDesc: CRTblDesc;
- Dir:array[0..255] of char;
- pFldArr : ^TFldArr;
- pOpArr : ^TOpArr;
- FldCount,NewCount,j : integer;
- SaveActive: boolean;
- FDesc: FldDesc;
- Props: CURPROPS;
- TableTypeName : PChar;
- begin
- with ATable do begin
- if Database.IsSqlBased then
- raise Exception.Create('Cannot restructure SQL tables');
- SaveActive:=Active;
- if not Active then Active := true;
- end;
- TableTypeName := GetTableTypeName(ATable);
- Check(DbiGetDirectory(ATable.DBHandle, False, Dir));
- Check(DbiGetCursorProps(ATable.Handle, Props));
- FldCount := Props.iFields;
- if OpType = resAdd then NewCount:=FldCount+1
- else NewCount := FldCount;
- if NewCount =0 then exit;
- pFldArr := AllocMem(NewCount * SizeOf(FLDDesc));
- pOpArr := AllocMem(NewCount * SizeOf(CROpType));
- Check(DbiGetFieldDescs(ATable.Handle, @pfldArr^[1]));
- try
- FillChar(TblDesc, sizeof(CRTblDesc), #0);
- TblDesc.bPack := True;
- case OpType of
- resModify : begin
- TblDesc.iFldCount := FldCount;
- with pFldArr^[FNum+1] do
- AnsiToNative(ATable.Locale, FName, szName, SizeOf(szName) - 1);
- pOpArr^[FNum+1]:=crModify;
- for j:=1 to TblDesc.iFldCount do
- pFldArr^[j].iFldNum := j;
- end;
-
- resAdd: begin
- TblDesc.iFldCount := FldCount+1;
- if FNum < FldCount then
- System.Move(pFldArr^[FNum+1],pFldArr^[FNum+2],
- (FldCount-FNum)*Sizeof(FldDesc));
- MapField(ATable,pFldArr^[FNum+1],FName,FType,FSize);
- pOpArr^[FNum+1]:=crAdd;
- for j:=1 to FNum do
- pFldArr^[j].iFldNum := j;
- if FNum < FldCount then
- for j:=FNum+2 to FldCount+1 do
- pFldArr^[j].iFldNum := j-1;
- end;
-
- resDrop: begin
- TblDesc.iFldCount := FldCount-1;
- if FNum < FldCount-1 then
- System.Move(pFldArr^[FNum+2],pFldArr^[FNum+1],
- (FldCount-FNum-1)*Sizeof(FldDesc));
- for j:=1 to FNum do
- pFldArr^[j].iFldNum := j;
- for j:=FNum+1 to FldCount-1 do
- pFldArr^[j].iFldNum := j+1;
- end;
-
- resMove: begin
- TblDesc.iFldCount := FldCount;
- for j:=1 to TblDesc.iFldCount do
- pFldArr^[j].iFldNum := j;
- FDesc := pFldArr^[FNum+1];
- if FDest > FNum then
- System.Move(pFldArr^[FNum+2],pFldArr^[FNum+1],
- (FDest-FNum)*Sizeof(FldDesc))
- else
- System.Move(pFldArr^[FDest+1],pFldArr^[FDest+2],
- (FNum-FDest)*Sizeof(FldDesc));
- pFldArr^[FDest+1]:=FDesc;
- end;
- end;
-
- ATable.Close;
- Check(DbiOpenDatabase(nil, nil, dbiReadWrite, dbiOpenExcl, nil, 0, nil, nil, hDb));
- Check(DbiSetDirectory(hDb, Dir));
- TblDesc.pFldDesc := @pFldArr^[1];
- TblDesc.pecrFldOp := @pOpArr^[1];
- if TableTypeName <> nil then
- StrCopy(TblDesc.szTblType, TableTypeName);
- StrPCopy(TblDesc.szTblName, ATable.TableName);
- Check(DbiDoRestructure(hDb, 1, @TblDesc, nil, nil, nil, False));
- finally
- Check(DbiCloseDatabase(hDb));
- FreeMem(pFldArr, NewCount * SizeOf(FLDDesc));
- FreeMem(pOpArr, NewCount * SizeOf(CROpType));
- if SaveActive then
- ATable.Open;
- end;
- end;
-
-
- end.
-